import { createApp } from "vue";
import MyMessageBox from './MyMessageBox.vue'

export interface MessageBoxProp {
  title?: string;
  message: string;
}

type ConfirmCallback = (done: () => void) => void // 确认回调
type CancelCallback = () => void // 取消回调
type MessageBox = {
  confirm: (cb: ConfirmCallback) => MessageBox,
  cancel: (cb: CancelCallback) => MessageBox
}

/**
 * @example
 *  confirmMessageBox({title: '确认删除？', message: '您确定要删除该数据？'})
 *    .confirm(done => {
 *      // 在合适的时机关闭弹窗
 *      done()
 *    })
 *    .confirm(done => {
 *      // confirm可以注册多个
 *    })
 *    .cancel(() => {
 *      // confirm也可以注册多个
 *    })
 *
 */
export const confirmMessageBox = (props: MessageBoxProp): MessageBox => {
  // 回调事件池
  const confirmEvents: ConfirmCallback[] = []
  let cancelEvents: CancelCallback[] = []

  // 创建一个容器，用来装vue渲染的内容
  const div = document.createElement('div')
  // 根组件的实例
  let instance: any
  // 创建App实例
  // 第二个参数是将传递给实例的props参数
  const app = createApp(MyMessageBox, {
    title: props.title,
    message: props.message,
    onConfirm: () => {
      // 执行确认事件池
      confirmEvents.forEach(cb => {
        cb(() => {
          instance?.hide()
          // 清空取消事件池，已经确认了，不需要取消事件了
          cancelEvents = []
        })
      })
    },
    onClosed: () => {
      document.body.removeChild(div)
      // 执行取消事件池
      cancelEvents.forEach(cb => {
        cb()
      })
    }
  })
  // 将实例渲染到容器中
  instance = app.mount(div)
  // 将渲染出的结果追加到页面
  document.body.appendChild(div)


  return {
    confirm(cb: ConfirmCallback) {
      confirmEvents.push(cb)
      return this
    },
    cancel(cb: CancelCallback) {
      cancelEvents.push(cb)
      return this
    }
  }
}
